"""
股票分析模块
负责技术分析、基本面分析和自定义策略
"""

import os
import json
import logging
from typing import Dict, List, Any, Optional
import pandas as pd
import numpy as np

logger = logging.getLogger(__name__)

class StockAnalyzer:
    """股票分析器"""
    
    def __init__(self):
        """初始化股票分析器"""
        self.results_dir = "results"
        self.analysis_config = {
            "technical_indicators": ["MA", "RSI", "MACD", "KDJ"],
            "timeframes": ["daily", "weekly", "monthly"],
            "signal_threshold": 0.6
        }
        
        # 确保结果目录存在
        os.makedirs(self.results_dir, exist_ok=True)
    
    def is_available(self) -> bool:
        """检查分析器是否可用"""
        try:
            import pandas as pd
            import numpy as np
            return True
        except ImportError:
            return False
    
    def technical_analysis(self):
        """技术分析"""
        print("正在进行技术分析...")
        
        try:
            # 获取股票列表
            from .data_manager import DataManager
            data_manager = DataManager()
            stocks = data_manager.get_stock_list()
            
            if not stocks:
                print("股票列表为空，请先更新股票列表")
                return
            
            # 限制分析数量
            stocks_to_analyze = stocks[:50]  # 只分析前50只股票
            
            print(f"开始分析 {len(stocks_to_analyze)} 只股票...")
            
            results = []
            for i, stock in enumerate(stocks_to_analyze):
                try:
                    stock_code = stock['code']
                    stock_name = stock['name']
                    
                    # 获取股票数据
                    data = data_manager.get_stock_data(stock_code)
                    
                    if data is not None and len(data) > 10:  # 至少需要10天数据
                        # 进行技术分析
                        analysis_result = self._analyze_technical_indicators(data, stock_code, stock_name)
                        
                        if analysis_result:
                            results.append(analysis_result)
                    
                    # 显示进度
                    if (i + 1) % 10 == 0:
                        print(f"已分析 {i + 1}/{len(stocks_to_analyze)} 只股票")
                        
                except Exception as e:
                    logger.error(f"分析股票 {stock['code']} 失败: {e}")
                    continue
            
            # 保存分析结果
            self._save_analysis_results(results, "technical_analysis")
            
            # 显示结果摘要
            self._display_analysis_summary(results)
            
        except Exception as e:
            print(f"技术分析时发生错误: {e}")
            logger.error(f"技术分析失败: {e}")
    
    def _analyze_technical_indicators(self, data: pd.DataFrame, stock_code: str, stock_name: str) -> Optional[Dict[str, Any]]:
        """分析技术指标"""
        try:
            # 确保数据列名正确
            if '日期' in data.columns:
                data = data.rename(columns={'日期': 'date'})
            if '收盘' in data.columns:
                data = data.rename(columns={'收盘': 'close'})
            if '开盘' in data.columns:
                data = data.rename(columns={'开盘': 'open'})
            if '最高' in data.columns:
                data = data.rename(columns={'最高': 'high'})
            if '最低' in data.columns:
                data = data.rename(columns={'最低': 'low'})
            if '成交量' in data.columns:
                data = data.rename(columns={'成交量': 'volume'})
            
            # 计算技术指标
            indicators = self._calculate_technical_indicators(data)
            
            # 生成交易信号
            signals = self._generate_trading_signals(data, indicators)
            
            # 计算综合评分
            score = self._calculate_composite_score(indicators, signals)
            
            if score > self.analysis_config["signal_threshold"]:
                return {
                    'stock_code': stock_code,
                    'stock_name': stock_name,
                    'score': score,
                    'indicators': indicators,
                    'signals': signals,
                    'analysis_date': pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')
                }
            
            return None
            
        except Exception as e:
            logger.error(f"分析股票 {stock_code} 技术指标失败: {e}")
            return None
    
    def _calculate_technical_indicators(self, data: pd.DataFrame) -> Dict[str, Any]:
        """计算技术指标"""
        indicators = {}
        
        try:
            # 移动平均线
            data['MA5'] = data['close'].rolling(window=5).mean()
            data['MA10'] = data['close'].rolling(window=10).mean()
            data['MA20'] = data['close'].rolling(window=20).mean()
            
            # RSI
            delta = data['close'].diff()
            gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
            loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
            rs = gain / loss
            data['RSI'] = 100 - (100 / (1 + rs))
            
            # MACD
            exp1 = data['close'].ewm(span=12).mean()
            exp2 = data['close'].ewm(span=26).mean()
            data['MACD'] = exp1 - exp2
            data['MACD_signal'] = data['MACD'].ewm(span=9).mean()
            data['MACD_histogram'] = data['MACD'] - data['MACD_signal']
            
            # KDJ
            low_min = data['low'].rolling(window=9).min()
            high_max = data['high'].rolling(window=9).max()
            rsv = (data['close'] - low_min) / (high_max - low_min) * 100
            data['K'] = rsv.ewm(com=2).mean()
            data['D'] = data['K'].ewm(com=2).mean()
            data['J'] = 3 * data['K'] - 2 * data['D']
            
            # 获取最新值
            latest = data.iloc[-1]
            indicators = {
                'MA5': latest['MA5'],
                'MA10': latest['MA10'],
                'MA20': latest['MA20'],
                'RSI': latest['RSI'],
                'MACD': latest['MACD'],
                'MACD_signal': latest['MACD_signal'],
                'K': latest['K'],
                'D': latest['D'],
                'J': latest['J']
            }
            
        except Exception as e:
            logger.error(f"计算技术指标失败: {e}")
        
        return indicators
    
    def _generate_trading_signals(self, data: pd.DataFrame, indicators: Dict[str, Any]) -> Dict[str, str]:
        """生成交易信号"""
        signals = {}
        
        try:
            # MA信号
            if indicators['MA5'] > indicators['MA10'] > indicators['MA20']:
                signals['MA'] = 'BUY'
            elif indicators['MA5'] < indicators['MA10'] < indicators['MA20']:
                signals['MA'] = 'SELL'
            else:
                signals['MA'] = 'HOLD'
            
            # RSI信号
            if indicators['RSI'] < 30:
                signals['RSI'] = 'BUY'
            elif indicators['RSI'] > 70:
                signals['RSI'] = 'SELL'
            else:
                signals['RSI'] = 'HOLD'
            
            # MACD信号
            if indicators['MACD'] > indicators['MACD_signal']:
                signals['MACD'] = 'BUY'
            else:
                signals['MACD'] = 'SELL'
            
            # KDJ信号
            if indicators['K'] > indicators['D'] and indicators['K'] < 20:
                signals['KDJ'] = 'BUY'
            elif indicators['K'] < indicators['D'] and indicators['K'] > 80:
                signals['KDJ'] = 'SELL'
            else:
                signals['KDJ'] = 'HOLD'
                
        except Exception as e:
            logger.error(f"生成交易信号失败: {e}")
        
        return signals
    
    def _calculate_composite_score(self, indicators: Dict[str, Any], signals: Dict[str, str]) -> float:
        """计算综合评分"""
        try:
            score = 0.0
            
            # MA评分
            if signals.get('MA') == 'BUY':
                score += 0.3
            elif signals.get('MA') == 'SELL':
                score -= 0.3
            
            # RSI评分
            if signals.get('RSI') == 'BUY':
                score += 0.25
            elif signals.get('RSI') == 'SELL':
                score -= 0.25
            
            # MACD评分
            if signals.get('MACD') == 'BUY':
                score += 0.25
            elif signals.get('MACD') == 'SELL':
                score -= 0.25
            
            # KDJ评分
            if signals.get('KDJ') == 'BUY':
                score += 0.2
            elif signals.get('KDJ') == 'SELL':
                score -= 0.2
            
            # 归一化到0-1范围
            score = (score + 1) / 2
            
            return max(0, min(1, score))
            
        except Exception as e:
            logger.error(f"计算综合评分失败: {e}")
            return 0.0
    
    def fundamental_analysis(self):
        """基本面分析"""
        print("基本面分析功能正在开发中...")
        print("该功能将包括:")
        print("- 财务指标分析")
        print("- 估值分析")
        print("- 行业对比分析")
        print("- 成长性分析")
    
    def custom_strategy(self):
        """自定义策略"""
        print("自定义策略功能正在开发中...")
        print("该功能将包括:")
        print("- 策略编辑器")
        print("- 回测功能")
        print("- 参数优化")
        print("- 策略组合")
    
    def view_results(self):
        """查看分析结果"""
        print("查看分析结果...")
        
        try:
            results_file = os.path.join(self.results_dir, "technical_analysis.json")
            
            if os.path.exists(results_file):
                with open(results_file, 'r', encoding='utf-8') as f:
                    results = json.load(f)
                
                print(f"\n技术分析结果 (共 {len(results)} 只股票):")
                print("-" * 80)
                
                # 按评分排序
                results.sort(key=lambda x: x['score'], reverse=True)
                
                for i, result in enumerate(results[:10], 1):  # 显示前10个结果
                    print(f"{i:2d}. {result['stock_code']} {result['stock_name']}")
                    print(f"    综合评分: {result['score']:.3f}")
                    print(f"    分析时间: {result['analysis_date']}")
                    
                    # 显示信号
                    signals = result.get('signals', {})
                    signal_text = []
                    for indicator, signal in signals.items():
                        signal_text.append(f"{indicator}:{signal}")
                    print(f"    交易信号: {', '.join(signal_text)}")
                    print()
                
                if len(results) > 10:
                    print(f"... 还有 {len(results) - 10} 只股票符合条件")
            else:
                print("没有找到分析结果文件")
                
        except Exception as e:
            print(f"查看分析结果时发生错误: {e}")
            logger.error(f"查看分析结果失败: {e}")
    
    def _save_analysis_results(self, results: List[Dict[str, Any]], analysis_type: str):
        """保存分析结果"""
        try:
            filename = os.path.join(self.results_dir, f"{analysis_type}.json")
            
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(results, f, ensure_ascii=False, indent=2)
            
            logger.info(f"分析结果已保存到: {filename}")
            
        except Exception as e:
            logger.error(f"保存分析结果失败: {e}")
    
    def _display_analysis_summary(self, results: List[Dict[str, Any]]):
        """显示分析摘要"""
        if not results:
            print("没有找到符合条件的股票")
            return
        
        print(f"\n分析完成!")
        print(f"符合条件的股票: {len(results)} 只")
        
        # 统计信号分布
        signal_counts = {'BUY': 0, 'SELL': 0, 'HOLD': 0}
        for result in results:
            signals = result.get('signals', {})
            for signal in signals.values():
                if signal in signal_counts:
                    signal_counts[signal] += 1
        
        print(f"信号分布:")
        print(f"  买入信号: {signal_counts['BUY']} 个")
        print(f"  卖出信号: {signal_counts['SELL']} 个")
        print(f"  持有信号: {signal_counts['HOLD']} 个")
        
        # 显示评分分布
        scores = [result['score'] for result in results]
        avg_score = np.mean(scores)
        max_score = np.max(scores)
        min_score = np.min(scores)
        
        print(f"评分统计:")
        print(f"  平均评分: {avg_score:.3f}")
        print(f"  最高评分: {max_score:.3f}")
        print(f"  最低评分: {min_score:.3f}")
